package model

import (
	"gorm.io/gorm"
)

type WebCategory struct {
	ID uint `gorm:"primary_key;AUTO_INCREMENT" json:"id" form:"id"`

	CategoryID uint   `gorm:"default:0" form:"category_id" binding:"required" json:"category_id"`
	Name       string `gorm:"type:text" form:"name" binding:"required" json:"name"`
	Webs       []Web  `gorm:"foreignKey:CategoryID;" json:"webs"`
	Private    bool   `gorm:"default:0" form:"private" binding:"required" json:"private"`
	Ord        int    `gorm:"default:0" form:"ord" binding:"required" json:"ord"` //排序

	SubWebCategory []WebCategory `gorm:"foreignKey:CategoryID" json:"sub_web_category"`
}

// 不显示私有分类
func onlyPublished(withPrivate bool) func(db *gorm.DB) *gorm.DB {
	if withPrivate {
		return func(db *gorm.DB) *gorm.DB {
			return db
		}
	}
	return func(db *gorm.DB) *gorm.DB {
		return db.Where("private=0")
	}
}

// Add 添加
func (m *WebCategory) Add() (id uint, err error) {
	err = db.Create(&m).Error
	if err == nil {
		id = m.ID
	}
	return
}

// Update 更新
func (m *WebCategory) Update() (err error) {
	if m.CategoryID != 0 {
		// 只能有2级分类
		var parent WebCategory
		db.First(&parent, m.CategoryID)
		if parent.CategoryID != 0 {
			m.CategoryID = 0
		}

		if parent.Private {
			m.Private = true
		}
	}
	err = db.Model(&WebCategory{}).Select("category_id", "name", "private").Where("id=?", m.ID).Updates(m).Error
	changePrivate(m)
	return
}

func changePrivate(item *WebCategory) {
	if item.CategoryID == 0 {
		var children []WebCategory
		db.Where("category_id=?", item.ID).Find(&children)
		var subsID []uint
		for _, sub := range children {
			subsID = append(subsID, sub.ID)
		}
		db.Model(&WebCategory{}).Where("category_id=?", item.ID).Update("private", item.Private)
		if len(subsID) > 0 {
			db.Model(&Web{}).Where("category_id in ?", subsID).Update("private", item.Private)
		}
	}
	db.Model(&Web{}).Where("category_id=?", item.ID).Update("private", item.Private)
}

// Delete 删除
func DeleteWebCategory(id uint) (err error) {
	err = db.Where("id=?", id).Delete(&WebCategory{}).Error
	if err == nil {
		db.Where("category_id=?", id).Delete(&Web{})
		db.Where("category_id=?", id).Delete(&WebCategory{})
	}
	return
}

// Get 获取
func GetWebCategory(withPrivate bool) (items []WebCategory, err error) {
	err = db.Where("category_id=0").Scopes(onlyPublished(withPrivate)).Order("ord asc").Find(&items).Error
	return
}

func GetWebSubCategory(id int, withPrivate bool) (item WebCategory, err error) {
	err = db.Preload("Webs", func(db *gorm.DB) *gorm.DB {
		return db.Scopes(onlyPublished(withPrivate))
	}).Where("id=?", id).Scopes(onlyPublished(withPrivate)).First(&item).Error
	if err == nil && item.CategoryID == 0 { // 顶级栏目时，获取子栏目
		var subs []WebCategory
		db.Where("category_id=?", id).Scopes(onlyPublished(withPrivate)).Order("name asc").Find(&subs)
		item.SubWebCategory = subs
	} else {
		item.SubWebCategory = []WebCategory{}
	}

	return
}

func GetAllWebCategories() (items []WebCategory, err error) {
	err = db.Find(&items).Error
	return
}

func GetAllWebCategoryData(withPrivate bool) (items []WebCategory, err error) {
	if withPrivate {
		err = db.Where("category_id=0").Preload("SubWebCategory", func(db *gorm.DB) *gorm.DB {
			return db.Order("name ASC")
		}).Preload("SubWebCategory.Webs").Preload("Webs").Order("ord asc").Find(&items).Error
	} else {
		err = db.Where("private=0 and category_id=0").Preload("SubWebCategory", func(db *gorm.DB) *gorm.DB {
			return db.Where("private=0").Order("name ASC")
		}).Preload("SubWebCategory.Webs", "private=0").Preload("Webs", "private=0").Order("ord asc").Find(&items).Error
	}
	return
}

func SetWebCategoryOrd(id uint, ord int) (err error) {
	err = db.Model(&WebCategory{}).Where("id=?", id).Update("ord", ord).Error
	return
}
